package top.codedance.iotp.tools.terminal.ui;

import top.codedance.iotp.common.util.SystemUtil;
import top.codedance.iotp.tools.terminal.TerminalApplication;
import top.codedance.iotp.tools.terminal.util.KeyStoreLoader;
import org.eclipse.milo.opcua.sdk.server.util.HostnameUtil;

import javax.swing.*;
import javax.swing.text.html.HTMLEditorKit;
import java.awt.*;
import java.io.File;
import java.net.URL;
import java.nio.file.Path;

/**
 * @author xuedianfu
 */
public class CertificateManage extends javax.swing.JDialog {
    public ShellFrame sf;
    private final WaitLoading waitLoading = new WaitLoading(this);
    private final String applicationName = "CodebanceOpcUaClient";
    private final String applicationUri = "urn:codebance:opcua:client";
    private final Path securityTempDir = new File(SystemUtil.getRuntimeDirPath(TerminalApplication.class)).toPath();
    private DefaultListModel dlmB;
    private final KeyStoreLoader loader = new KeyStoreLoader();

    /**
     * Creates new form CertificateManage
     */
    public CertificateManage(ShellFrame sf) {
        super(sf, true);
        this.sf = sf;
        initComponents();
        URL url = Thread.currentThread().getContextClassLoader().getResource("logo.gif");
        ImageIcon icon = new ImageIcon(url);
        setIconImage(icon.getImage());
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setMinimumSize(new Dimension(600, 400));
        setLocationRelativeTo(this.sf);
        setTitle("代码飞舞采控系统-证书管理器");

        initList();
    }

    private void initList() {
        dlmB = new DefaultListModel();
        this.jl_certificate.setModel(dlmB);
        initCmdHelpData();
    }

    private void initCmdHelpData() {
        loader.initFilePath(securityTempDir);
        dlmB.clear();
        if(loader.getExportCertFile().toFile().exists()) {
            dlmB.addElement(loader.getExportCertFile().toFile().getAbsolutePath());
        }
        if(loader.getServerKeyStore().toFile().exists()) {
            dlmB.addElement(loader.getServerKeyStore().toFile().getAbsolutePath());
        }
        if(loader.getExportPublicFile().toFile().exists()) {
            dlmB.addElement(loader.getExportPublicFile().toFile().getAbsolutePath());
        }
        if(loader.getExportPrivateFile().toFile().exists()) {
            dlmB.addElement(loader.getExportPrivateFile().toFile().getAbsolutePath());
        }
        if(loader.getExportHash().toFile().exists()) {
            dlmB.addElement(loader.getExportHash().toFile().getAbsolutePath());
        }
        this.jl_certificate.repaint();
    }

    private void waiting(){
        waitLoading.open();
    }

    private void over(){
        if(waitLoading != null) {
            waitLoading.close();
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jb_gen = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jl_certificate = new javax.swing.JList<>();
        jb_del = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jcb_strength = new javax.swing.JComboBox<>();
        jLabel2 = new javax.swing.JLabel();
        jcb_algorithm = new javax.swing.JComboBox<>();
        jLabel3 = new javax.swing.JLabel();
        jcb_validity = new javax.swing.JComboBox<>();
        jLabel4 = new javax.swing.JLabel();
        jcb_sha = new javax.swing.JComboBox<>();
        jcb_sign = new javax.swing.JCheckBox();
        jb_viewHostname = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        jb_gen.setText("创建新证书");
        jb_gen.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jb_genActionPerformed(evt);
            }
        });

        jScrollPane1.setViewportView(jl_certificate);

        jb_del.setText("删除证书");
        jb_del.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jb_delActionPerformed(evt);
            }
        });

        jLabel1.setText("RSA密钥强度：");

        jcb_strength.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "2048", "3072", "4096", "1024" }));

        jLabel2.setText("签名算法：");

        jcb_algorithm.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "PKCS12", "JKS", "JCEKS", "DKS" }));

        jLabel3.setText("证书有效期：");

        jcb_validity.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "1", "3", "5", "10", "50", "100" }));

        jLabel4.setText("签名和验证：");

        jcb_sha.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "SHA-256", "SHA", "SHA-1", "SHA-224", "SHA-384", "SHA-512", "MD2", "MD5" }));

        jcb_sign.setText("启用签名");

        jb_viewHostname.setText("查看本机名");
        jb_viewHostname.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jb_viewHostnameActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 756, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jcb_strength, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jcb_algorithm, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jcb_validity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jLabel4)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jcb_sha, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jcb_sign)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(jb_gen)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jb_del)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jb_viewHostname)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(jcb_strength, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2)
                    .addComponent(jcb_algorithm, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3)
                    .addComponent(jcb_validity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel4)
                    .addComponent(jcb_sha, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jcb_sign))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 412, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jb_gen)
                    .addComponent(jb_del)
                    .addComponent(jb_viewHostname))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jb_genActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jb_genActionPerformed
        final Integer strength = Integer.valueOf(jcb_strength.getSelectedItem().toString());
        final String algorithm = jcb_algorithm.getSelectedItem().toString();
        final Integer validity = Integer.valueOf(jcb_validity.getSelectedItem().toString());
        final boolean sign = jcb_sign.isSelected();
        final String hash = jcb_sha.getSelectedItem().toString();
        waiting();
        TerminalApplication.pool.submit(() -> {
            try {
                CertificateManage.this.loader.load(securityTempDir, strength, algorithm, validity, sign, hash, applicationName, applicationUri);
            } catch (Exception e) {
                TerminalApplication.syslogInfo(e.getMessage());
                JOptionPane.showMessageDialog(rootPane, "生成证书失败。");
            } finally {
                over();
                CertificateManage.this.initCmdHelpData();
            }
        });
    }//GEN-LAST:event_jb_genActionPerformed

    private void jb_delActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jb_delActionPerformed
        if(loader.getExportCertFile().toFile().exists()) {
            loader.getExportCertFile().toFile().delete();
        }
        if(loader.getServerKeyStore().toFile().exists()) {
            loader.getServerKeyStore().toFile().delete();
        }
        if(loader.getExportPublicFile().toFile().exists()) {
            loader.getExportPublicFile().toFile().delete();
        }
        if(loader.getExportPrivateFile().toFile().exists()) {
            loader.getExportPrivateFile().toFile().delete();
        }
        if(loader.getExportHash().toFile().exists()) {
            loader.getExportHash().toFile().delete();
        }
        initCmdHelpData();
    }//GEN-LAST:event_jb_delActionPerformed

    private void jb_viewHostnameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jb_viewHostnameActionPerformed
        StringBuilder sm = new StringBuilder();
        for (String hostname : HostnameUtil.getHostnames("0.0.0.0")) {
            sm.append(hostname);
            sm.append("<br />");
        }
        JTextPane textPane = new JTextPane();
        textPane.setEditable(false);
        textPane.setContentType("text/html");
        textPane.setEditorKit(new HTMLEditorKit());
        textPane.setText(sm.toString());
        JOptionPane.showMessageDialog(rootPane, textPane, "Host内容", JOptionPane.INFORMATION_MESSAGE);
    }//GEN-LAST:event_jb_viewHostnameActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JButton jb_del;
    private javax.swing.JButton jb_gen;
    private javax.swing.JButton jb_viewHostname;
    private javax.swing.JComboBox<String> jcb_algorithm;
    private javax.swing.JComboBox<String> jcb_sha;
    private javax.swing.JCheckBox jcb_sign;
    private javax.swing.JComboBox<String> jcb_strength;
    private javax.swing.JComboBox<String> jcb_validity;
    private javax.swing.JList<String> jl_certificate;
    // End of variables declaration//GEN-END:variables
}
